{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# Using ZhipuAI GLM-4 in Langchain\n",
    "\n",
    "**This tutorial is available in English and is attached below the Chinese explanation**\n",
    "\n",
    "本代码，我们将带领大家如何使用 Langchain 来调用 ZhipuAI 的 GLM-4 模型。\n",
    "你将在本章节学习到如何使用 Langchain 的 `ChatZhipuAI` 类来调用 ZhipuAI 的 GLM-4 模型，以及如何使用 `ChatZhipuAI` 类来实现类似 `ChatOpenAI` 的方法来进行调用。\n",
    "\n",
    "In this notebook, I will show you how to use Langchain to call ZhipuAI's GLM-4 model.\n",
    "In this chapter, you will learn how to use Langchain's `ChatZhipuAI` class to call ZhipuAI's GLM-4 model, and how to use the `ChatZhipuAI` class to implement methods similar to `ChatOpenAI` to make calls."
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "71c55dc5a09277b"
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 1. Install Langchain\n",
    "\n",
    "由于本教程需要使用 Langchain进行调用，因此我们首先需要安装 Langchain 和 对应的依赖包。 请确保 langchain_community 的版本在 0.0.32 以上。\n",
    "\n",
    "Since this tutorial requires Langchain to be called, you first need to install Langchain and the corresponding dependency packages. Make sure that the version of langchain_community is above 0.0.32."
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "4d50b54cbc991843"
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: langchain in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (0.1.15)\r\n",
      "Requirement already satisfied: langchainhub in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (0.1.15)\r\n",
      "Requirement already satisfied: httpx_sse in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (0.4.0)\r\n",
      "Requirement already satisfied: PyYAML>=5.3 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchain) (6.0.1)\r\n",
      "Requirement already satisfied: SQLAlchemy<3,>=1.4 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchain) (2.0.25)\r\n",
      "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchain) (3.9.3)\r\n",
      "Requirement already satisfied: async-timeout<5.0.0,>=4.0.0 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchain) (4.0.3)\r\n",
      "Requirement already satisfied: dataclasses-json<0.7,>=0.5.7 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchain) (0.6.3)\r\n",
      "Requirement already satisfied: jsonpatch<2.0,>=1.33 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchain) (1.33)\r\n",
      "Requirement already satisfied: langchain-community<0.1,>=0.0.32 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchain) (0.0.32)\r\n",
      "Requirement already satisfied: langchain-core<0.2.0,>=0.1.41 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchain) (0.1.41)\r\n",
      "Requirement already satisfied: langchain-text-splitters<0.1,>=0.0.1 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchain) (0.0.1)\r\n",
      "Requirement already satisfied: langsmith<0.2.0,>=0.1.17 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchain) (0.1.40)\r\n",
      "Requirement already satisfied: numpy<2,>=1 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchain) (1.26.3)\r\n",
      "Requirement already satisfied: pydantic<3,>=1 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchain) (2.5.3)\r\n",
      "Requirement already satisfied: requests<3,>=2 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchain) (2.31.0)\r\n",
      "Requirement already satisfied: tenacity<9.0.0,>=8.1.0 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchain) (8.2.3)\r\n",
      "Requirement already satisfied: types-requests<3.0.0.0,>=2.31.0.2 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchainhub) (2.31.0.20240125)\r\n",
      "Requirement already satisfied: aiosignal>=1.1.2 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.3.1)\r\n",
      "Requirement already satisfied: attrs>=17.3.0 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (23.2.0)\r\n",
      "Requirement already satisfied: frozenlist>=1.1.1 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.4.1)\r\n",
      "Requirement already satisfied: multidict<7.0,>=4.5 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (6.0.4)\r\n",
      "Requirement already satisfied: yarl<2.0,>=1.0 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.9.4)\r\n",
      "Requirement already satisfied: marshmallow<4.0.0,>=3.18.0 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from dataclasses-json<0.7,>=0.5.7->langchain) (3.20.2)\r\n",
      "Requirement already satisfied: typing-inspect<1,>=0.4.0 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from dataclasses-json<0.7,>=0.5.7->langchain) (0.9.0)\r\n",
      "Requirement already satisfied: jsonpointer>=1.9 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from jsonpatch<2.0,>=1.33->langchain) (2.4)\r\n",
      "Requirement already satisfied: packaging<24.0,>=23.2 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langchain-core<0.2.0,>=0.1.41->langchain) (23.2)\r\n",
      "Requirement already satisfied: orjson<4.0.0,>=3.9.14 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from langsmith<0.2.0,>=0.1.17->langchain) (3.10.0)\r\n",
      "Requirement already satisfied: annotated-types>=0.4.0 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from pydantic<3,>=1->langchain) (0.6.0)\r\n",
      "Requirement already satisfied: pydantic-core==2.14.6 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from pydantic<3,>=1->langchain) (2.14.6)\r\n",
      "Requirement already satisfied: typing-extensions>=4.6.1 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from pydantic<3,>=1->langchain) (4.9.0)\r\n",
      "Requirement already satisfied: charset-normalizer<4,>=2 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from requests<3,>=2->langchain) (3.3.2)\r\n",
      "Requirement already satisfied: idna<4,>=2.5 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from requests<3,>=2->langchain) (3.6)\r\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from requests<3,>=2->langchain) (2.2.0)\r\n",
      "Requirement already satisfied: certifi>=2017.4.17 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from requests<3,>=2->langchain) (2023.11.17)\r\n",
      "Requirement already satisfied: mypy-extensions>=0.3.0 in /Users/zr/Code/glm-cookbook/venv/lib/python3.9/site-packages (from typing-inspect<1,>=0.4.0->dataclasses-json<0.7,>=0.5.7->langchain) (1.0.0)\r\n",
      "\u001B[33mDEPRECATION: textract 1.6.5 has a non-standard dependency specifier extract-msg<=0.29.*. pip 24.1 will enforce this behaviour change. A possible replacement is to upgrade to a newer version of textract or contact the author to suggest that they release a version with a conforming dependency specifiers. Discussion can be found at https://github.com/pypa/pip/issues/12063\u001B[0m\u001B[33m\r\n",
      "\u001B[0m"
     ]
    }
   ],
   "source": [
    "! pip install langchain langchainhub httpx_sse"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-04-10T06:20:36.129061Z",
     "start_time": "2024-04-10T06:20:34.451411Z"
    }
   },
   "id": "56028f01ac7638e0"
  },
  {
   "cell_type": "markdown",
   "source": [
    "现在，设置好 ZhipuAI 的 API Key，这样我们就可以使用 ZhipuAI 的 GLM-4 模型了。\n",
    "Now, you need to set up ZhipuAI’s API Key so that you can use ZhipuAI’s GLM-4 model.\n",
    "> 如果你需要使用本章节的第 4 部分教程，你需要填写 TAVILY_API_KEY，该工具用于执行 Langchain 的 工具调用。\n",
    "If you need to use the fourth part of the tutorial in this chapter, you need to fill in TAVILY_API_KEY, which is used to execute Langchain’s tool calls."
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "d5e70f847aa90565"
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "os.environ[\"ZHIPUAI_API_KEY\"] = \"your zhipu api key\"\n",
    "os.environ[\"TAVILY_API_KEY\"] = \"your tavily api key\""
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-30T07:57:46.263648Z",
     "start_time": "2024-01-30T07:57:46.259381Z"
    }
   },
   "id": "e5c8299e0683b8b"
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 2. Use the method of `ChatZhipuAI` class to call ZhipuAI’s GLM-4 model\n",
    "\n",
    "和 `ChatOpenAI` 类一样，`ChatZhipuAI` 类也是一个可以调用 ZhipuAI 的 GLM-4 模型的类，我们可以使用 `ChatZhipuAI`来替换 `ChatOpenAI` 类，直接无缝对接到自己的项目中。这里展现了一个最基本的调用方法。\n",
    "\n",
    "Like the `ChatOpenAI` class, the `ChatZhipuAI` class is also a class that can call ZhipuAI's GLM-4 model. you can use `ChatZhipuAI` to replace the `ChatOpenAI` class and directly and seamlessly connect it to our own projects. Here is a basic calling method."
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "e31b191a56f0f6ec"
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "outputs": [
    {
     "data": {
      "text/plain": "AIMessage(content=\"Ah, this is a classic riddle. The answer is that there were still 9 birds on the tree, but one of them was now dead. The riddle plays on the assumption that the number of birds decreases after one is shot, but it doesn't account for the dead bird still being on the tree. Remember, riddles are meant to be clever and often rely on wordplay or a twist in logic!\")"
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_community.chat_models.zhipuai import ChatZhipuAI\n",
    "from langchain.schema import HumanMessage, SystemMessage\n",
    "\n",
    "messages = [\n",
    "\n",
    "    SystemMessage(\n",
    "        content=\"You are a smart assistant, please reply to me smartly.\"\n",
    "    ),\n",
    "    HumanMessage(\n",
    "        content=\"There were 9 birds on the tree. The hunter shot and killed one. How many birds were there?\"\n",
    "    ),\n",
    "]\n",
    "\n",
    "llm = ChatZhipuAI(\n",
    "    temperature=0.95,\n",
    "    model=\"glm-4\"\n",
    ")\n",
    "\n",
    "llm(messages)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-30T07:57:50.490182Z",
     "start_time": "2024-01-30T07:57:46.265531Z"
    }
   },
   "id": "88e74dc43ab33e2"
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 3. Use Langchain to call your own fine-tuned model.\n",
    "\n",
    "ZhipuAI 已经支持使用 Langchain 调用微调的 ChatGLM 系列模型，如果你想学习如何微调模型，请查看[微调教程](../finetune/glm_lora_finetune_pysdk.ipynb) 来微调自己的模型。\n",
    "\n",
    "ZhipuAI already supports using Langchain to call the fine-tuned ChatGLM series models. If you want to learn how to fine-tune the model, please view the [Fine-tuning Tutorial](../finetune/glm_lora_finetune_pysdk.ipynb) to fine-tune your own model"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "94dd61f74ceb10f5"
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [
    {
     "data": {
      "text/plain": "AIMessage(content='这件裤子是英伦风格的简约设计,具有时尚的元素,但同时保持了经典和优雅的氛围。它可能由高质量的面料制成,具有舒适的贴身感和耐用性。这条裤子适合许多场合,可以搭配各种衣服,如T恤、衬衫、外套等。它也是一条非常百搭的裤子,可以轻松地搭配各种鞋子,如运动鞋、皮鞋、凉鞋等。这条裤子是英伦风格简约设计的代表作品,既时尚又经典,是每个人衣橱中必备的单品。')"
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "messages = [\n",
    "    HumanMessage(\n",
    "        content=\"类型#裤*风格#英伦*风格#简约\"\n",
    "    ),\n",
    "]\n",
    "fine_tuned_model = ChatZhipuAI(\n",
    "    temperature=0.2, model_name=\"ft:chatglm3-6b:advertise_gen:sg59pfxk\"\n",
    ")\n",
    "fine_tuned_model(messages)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-30T07:57:52.659556Z",
     "start_time": "2024-01-30T07:57:50.490161Z"
    }
   },
   "id": "e6f5773c7a88debb"
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 4. 使用 Langchain 来完成一个简单的 Function Call 调用\n",
    "\n",
    "得益于 ZhipuAI 也具有极强的 工具调用能力，你可以使用它来完成 Langchain中的 `Agent` 类的功能，这里我们展示了一个简单的调用方法。\n",
    "\n",
    "我参考 [Langchain 官方教程](https://python.langchain.com/docs/modules/agents/agent_types/openai_functions_agent) 的方案，并仅仅将 `ChatOpenAI`替换为`ChatZhipuAI`，除了模型加载方式，在 Agent 代码中完全不用进行任何代码修改。\n",
    "\n",
    "Thanks to ZhipuAI's strong tool calling capabilities, you can use it to complete the functions of the `Agent` class in Langchain. Here we show a simple calling method.\n",
    "\n",
    "I refer to the solution of [Langchain official tutorial](https://python.langchain.com/docs/modules/agents/agent_types/openai_functions_agent) and just replace `ChatOpenAI` with `ChatZhipuAI`. Except for the model loading method, in Agent There is absolutely no need to make any code modifications in the code.\n",
    "\n"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "d812902132ada30e"
  },
  {
   "cell_type": "markdown",
   "source": [],
   "metadata": {
    "collapsed": false
   },
   "id": "8f27d3a8564b9549"
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "outputs": [],
   "source": [
    "from langchain import hub\n",
    "from langchain.agents import AgentExecutor, create_json_chat_agent\n",
    "from langchain_community.tools.tavily_search import TavilySearchResults\n",
    "tools = [TavilySearchResults(max_results=1)]\n",
    "prompt = hub.pull(\"hwchase17/react-chat-json\")\n",
    "agent = create_json_chat_agent(llm, tools, prompt)\n",
    "agent_executor = AgentExecutor(\n",
    "    agent=agent, tools=tools, verbose=True, handle_parsing_errors=True\n",
    ")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-30T07:57:54.662559Z",
     "start_time": "2024-01-30T07:57:52.657035Z"
    }
   },
   "id": "8ade454081305502"
  },
  {
   "cell_type": "markdown",
   "source": [
    "接着，我们执行这个代码，就可以获得正确的答案。观察到智谱AI 能直接无缝的使用 Langchain 的 `Agent` 类的功能。\n",
    "Then, we execute this code and get the correct answer. It is observed that Zhipu AI can directly and seamlessly use the functions of Langchain's `Agent` class."
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "7bd4dd9dd81c448"
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new AgentExecutor chain...\u001B[0m\n",
      "\u001B[32;1m\u001B[1;3m```json\n",
      "{\n",
      "    \"action\": \"tavily_search_results_json\",\n",
      "    \"action_input\": \"LangChain\"\n",
      "}\n",
      "```\u001B[0m\u001B[36;1m\u001B[1;3m[{'url': 'https://blog.stackademic.com/langchain-in-chains-1-a-closer-look-a6bbaa246ccb', 'content': 'Langchain  LangChain is an open-source framework designed to simplify the creation of applications using large language models  Langchain provides various components that make it easier to integrate and manage models in different application  LangChain is a framework for developing applications powered by language models. It enables applications that:The LLMs and Chat Models component of Langchain provides a framework for integrating and managing various large language models (LLMs), including specialized chat models, within applications. Prompts and Parsers streamline the model inputs and outputs. In the subsequent sections of this series, we will closely examine each concept. Next:'}]\u001B[0m\u001B[32;1m\u001B[1;3m```json\n",
      "{\n",
      "    \"action\": \"Final Answer\",\n",
      "    \"action_input\": \"LangChain is an open-source framework designed to simplify the creation of applications using large language models. It provides various components that make it easier to integrate and manage models in different applications, enabling the development of applications powered by language models. This includes integrating and managing large language models and chat models, as well as streamlining model inputs and outputs with prompts and parsers.\"\n",
      "}\n",
      "```\u001B[0m\n",
      "\n",
      "\u001B[1m> Finished chain.\u001B[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": "{'input': 'what is LangChain?',\n 'output': 'LangChain is an open-source framework designed to simplify the creation of applications using large language models. It provides various components that make it easier to integrate and manage models in different applications, enabling the development of applications powered by language models. This includes integrating and managing large language models and chat models, as well as streamlining model inputs and outputs with prompts and parsers.'}"
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent_executor.invoke({\"input\": \"what is LangChain?\"})"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-01-30T07:58:11.179922Z",
     "start_time": "2024-01-30T07:57:54.664525Z"
    }
   },
   "id": "e5bc6d699ea277a5"
  },
  {
   "cell_type": "markdown",
   "source": [
    "## Conclusion\n",
    "\n",
    "通过本教程，您将能快速的切换 `Langchain` 的模型读入，将模型切换为 ZhipuAI 的 GLM-4 系列模型。本代码只是基础教程，我将于之后推出更多进阶的使用 GLM-4 系列模型和 Langchain 的配合作品。\n",
    "\n",
    "Through this tutorial, you will be able to quickly switch to `Langchain` model reading and switch the model to ZhipuAI's GLM-4 series model. This code is just a basic tutorial. I will launch more advanced works using GLM-4 series models and Langchain in the future."
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "d9f3b64b6ef3fd40"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
